#!/usr/bin/env ruby

require 'nokogiri'
require 'Version'

class Xml
  COMPOSITE = "composite"
  POM = "pom"
  BPEL = "bpel"
  BPMN = "bpmn"
  MEDIATOR = "mediator"
  SPRING = "spring"
  DECISION = "decision"
  XMLNS = "xmlns"
  WSDL = "wsdl"
  
  attr_accessor :doc, :path, :info, :version
  
  def initialize(doc = nil)
    if doc.class == Nokogiri::XML::Document
      @doc = doc
    elsif  doc.class == ''.class
      loadDoc(doc)
    end
  end

  def loadDoc(path=@path)
    file = File.open(path)
    if File.exist?(path)
      @doc = Nokogiri::XML(File.open(@path=path))
      return true
    end
    false
  end

  def isDoc?
    return true if @doc.class == Nokogiri::XML::Document
    false
  end

  def info
    Hash["name"=>name,"revision"=>version,"type"=>type]
  end

  def name
    node=@doc.xpath('//@name')[0]
    node=@doc.xpath('//xmlns:artifactId')[0] if type == POM
    if node == nil
      @doc.child["name"]=type
      node=@doc.xpath('//@name')[0]
    end
    node.content
  end
  
  def type
    path.split("/")[-1][0..-5].downcase
  end
  
  def versionNode
    @node=@doc.xpath('//@revision')[0] if type == COMPOSITE
    @node=@doc.xpath('//xmlns:version')[0] if type == POM
    @node=@doc.xpath('//@version')[0] if @node == nil
    if @node == nil
      @doc.elements[0]["version"]=""
      @node=@doc.xpath('//@version')[0]
    end
    @node
  end

  def version
    @version=Version.new(versionNode.content) if @version==nil
    @version
  end

  def version=(vers)
    if @version==nil
      @version=Version.new(vers) 
    else
      @version.version=vers
    end
    versionNode.content=@version.to_s
    @version
  end

  def push
    File.open(path,'w'){|f| f.write(@doc.to_xml)} if isDoc?
    info
  end
  
  def node_document?(node)
      !node.nil? and node.name == "document"
  end

  def to_s
    info.to_s
  end

  def to_xml
    @doc.to_xml
  end
  
  def node_path(node=nil)
    path = node.path if !node.nil?
    path = @doc.path if path.nil?
    path
  end

  def documentation(node=nil)
    node = @doc.elements[0] if node.nil?
    desc = node.xpath("#{(node.path == "/") ? "" : node.path}//*[local-name()='documentation']")[0]
    desc = desc.text if !desc.nil?
    desc
  end

  def namespace(name=nil)
    return @doc.elements[0].namespace.href if name.nil?
    ns = @doc.namespaces["xmlns:"+name.split(":")[0]]
    ns = @doc.collect_namespaces["xmlns:"+name.split(":")[0]] if ns.nil?
    ns = @doc.namespaces["xmlns"] if ns.nil?
    return ns
  end

  def qname(node=nil)
    node = @doc.elements[0] if node.nil?
    if node.class == "".class
      ns = namespace(node)
      name = node.split(":")[-1]
    else
      ns = node.namespace.href if !node.namespace.nil?
      ns = namespace(node.name) if ns.nil?
      name = node.name
    end
    return "{" + ns + "}" + name
  end

  def imports
    if isDoc?
      return doc.xpath("//*[contains('import,include',local-name())]")
    end
    nil
  end
  
  def self.find_path(path,directory=nil)
    sep = "**"
    sep = sep + "/" if path.first != "/"

    directory = "." if directory.nil? or directory.size < 1
    sep = "/" + sep if directory.last != "/"

    Dir[directory+sep+path.split(":")[-1]][0]

#     `find #{(directory)} -wholename "*#{path.split(":")[-1]}" -prune -nowarn`.split("\n")[0]
  end

end
